<!DOCTYPE html>
<html lang="zh-cn"><head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <link href="/css/main.css" rel="stylesheet">

    <link rel="shortcut icon" type="image/x-icon" href="/img/favicon.ico" />

    <title>Go程序的指针 | wiseAI的小站</title>
</head><body><div class="container-fluid">
    <nav class="navbar fixed-top navbar-expand-sm navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="/">
                <img src="/img/favicon.ico" alt="" width="30" height="24" class="d-inline-block align-text-top">
                wiseAI的小站
            </a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/articles/">文章</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/categories/">分类</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/tags/">关键字</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/post/golang/">golang编程</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/about/">关于</a>
                    </li>
                    
                </ul>
                <form class="d-flex">
                    <input id="search-query" class="form-control me-2" type="search" placeholder="Search for anything..." aria-label="Search">
                </form>
            </div>
        </div>
    </nav>
</div>




<div id="content">
<div class="container article">
	<h1>Go程序的指针</h1>
	<div class="post-meta">
		<div>
			
			
			By wiseai | 2022-07-06 | 2 minutes
		</div>
		<div class="tags">
			
			<a class="btn btn-light links btn-sm" href="/tags/%E7%BC%96%E7%A8%8B/">编程</a>
			
		</div>
	</div>
	<div>
		<div class="article-post">
			<h1 id="49-指针">4.9 指针</h1>
<p>不像 Java 和 .NET，Go 语言为程序员提供了控制数据结构的指针的能力；但是，你不能进行指针运算。通过给予程序员基本内存布局，Go 语言允许你控制特定集合的数据结构、分配的数量以及内存访问模式，这些对构建运行良好的系统是非常重要的：指针对于性能的影响是不言而喻的，而如果你想要做的是系统编程、操作系统或者网络应用，指针更是不可或缺的一部分。</p>
<p>由于各种原因，指针对于使用面向对象编程的现代程序员来说可能显得有些陌生，不过我们将会在这一小节对此进行解释，并在未来的章节中展开深入讨论。</p>
<p>程序在内存中存储它的值，每个内存块（或字）有一个地址，通常用十六进制数表示，如：<code>0x6b0820</code> 或 <code>0xf84001d7f0</code>。</p>
<p>Go 语言的取地址符是 <code>&amp;</code>，放到一个变量前使用就会返回相应变量的内存地址。</p>
<p>下面的代码片段（示例 4.9 <a href="examples/chapter_4/pointer.go">pointer.go</a>）可能输出 <code>An integer: 5, its location in memory: 0x6b0820</code>（这个值随着你每次运行程序而变化）。</p>
<pre tabindex="0"><code>var i1 = 5
fmt.Printf(&#34;An integer: %d, it&#39;s location in memory: %p\n&#34;, i1, &amp;i1)
</code></pre><p>这个地址可以存储在一个叫做指针的特殊数据类型中，在本例中这是一个指向 int 的指针，即 <code>i1</code>：此处使用 <code>*int</code> 表示。如果我们想调用指针 <code>intP</code>，我们可以这样声明它：</p>
<pre tabindex="0"><code>var intP *int
</code></pre><p>然后使用 <code>intP = &amp;i1</code> 是合法的，此时 <code>intP</code> 指向 <code>i1</code>。</p>
<p>（指针的格式化标识符为 <code>%p</code>）</p>
<p><code>intP</code> 存储了 <code>i1</code> 的内存地址；它指向了 <code>i1</code> 的位置，它引用了变量 <code>i1</code>。</p>
<p><strong>一个指针变量可以指向任何一个值的内存地址</strong> 它指向那个值的内存地址，在 32 位机器上占用 4 个字节，在 64 位机器上占用 8 个字节，并且与它所指向的值的大小无关。当然，可以声明指针指向任何类型的值来表明它的原始性或结构性；你可以在指针类型前面加上 <code>*</code> 号（前缀）来获取指针所指向的内容，这里的 <code>*</code> 号是一个类型更改器。使用一个指针引用一个值被称为间接引用。</p>
<p>当一个指针被定义后没有分配到任何变量时，它的值为 <code>nil</code>。</p>
<p>一个指针变量通常缩写为 <code>ptr</code>。</p>
<p><strong>注意事项</strong></p>
<p>在书写表达式类似 <code>var p *type</code> 时，切记在 * 号和指针名称间留有一个空格，因为 <code>- var p*type</code> 是语法正确的，但是在更复杂的表达式中，它容易被误认为是一个乘法表达式！</p>
<p>符号 * 可以放在一个指针前，如 <code>*intP</code>，那么它将得到这个指针指向地址上所存储的值；这被称为反引用（或者内容或者间接引用）操作符；另一种说法是指针转移。</p>
<p>对于任何一个变量 <code>var</code>， 如下表达式都是正确的：<code>var == *(&amp;var)</code>。</p>
<p>现在，我们应当能理解 pointer.go 的全部内容及其输出：</p>
<p>示例 4.21 <a href="examples/chapter_4/pointer.go">pointer.go</a>:</p>
<pre tabindex="0"><code>package main
import &#34;fmt&#34;
func main() {
	var i1 = 5
	fmt.Printf(&#34;An integer: %d, its location in memory: %p\n&#34;, i1, &amp;i1)
	var intP *int
	intP = &amp;i1
	fmt.Printf(&#34;The value at memory location %p is %d\n&#34;, intP, *intP)
}
</code></pre><p>输出：</p>
<pre><code>An integer: 5, its location in memory: 0x24f0820
The value at memory location 0x24f0820 is 5
</code></pre>
<p>我们可以用下图来表示内存使用的情况：</p>
<img src="images/4.9_fig4.4.png?raw=true" style="zoom:67%;" />
<p>程序 string_pointer.go 为我们展示了指针对 <code>string</code> 的例子。</p>
<p>它展示了分配一个新的值给 <code>*p</code> 并且更改这个变量自己的值（这里是一个字符串）。</p>
<p>示例 4.22 <a href="examples/chapter_4/string_pointer.go">string_pointer.go</a></p>
<pre tabindex="0"><code>package main
import &#34;fmt&#34;
func main() {
	s := &#34;good bye&#34;
	var p *string = &amp;s
	*p = &#34;ciao&#34;
	fmt.Printf(&#34;Here is the pointer p: %p\n&#34;, p) // prints address
	fmt.Printf(&#34;Here is the string *p: %s\n&#34;, *p) // prints string
	fmt.Printf(&#34;Here is the string s: %s\n&#34;, s) // prints same string
}
</code></pre><p>输出：</p>
<pre><code>Here is the pointer p: 0x2540820
Here is the string *p: ciao
Here is the string s: ciao
</code></pre>
<p>通过对 <code>*p</code> 赋另一个值来更改“对象”，这样 <code>s</code> 也会随之更改。</p>
<p>内存示意图如下：</p>
<img src="images/4.9_fig4.5.png?raw=true" style="zoom:67%;" />
<p><strong>注意事项</strong></p>
<p>你不能获取字面量或常量的地址，例如：</p>
<pre tabindex="0"><code>const i = 5
ptr := &amp;i //error: cannot take the address of i
ptr2 := &amp;10 //error: cannot take the address of 10
</code></pre><p>所以说，Go 语言和 C、C++ 以及 D 语言这些低级（系统）语言一样，都有指针的概念。但是对于经常导致 C 语言内存泄漏继而程序崩溃的指针运算（所谓的指针算法，如：<code>pointer+2</code>，移动指针指向字符串的字节数或数组的某个位置）是不被允许的。Go 语言中的指针保证了内存安全，更像是 Java、C# 和 VB.NET 中的引用。</p>
<p>因此 <code>p++</code> 在 Go 语言的代码中是不合法的。</p>
<p>指针的一个高级应用是你可以传递一个变量的引用（如函数的参数），这样不会传递变量的拷贝。指针传递是很廉价的，只占用 4 个或 8 个字节。当程序在工作中需要占用大量的内存，或很多变量，或者两者都有，使用指针会减少内存占用和提高效率。被指向的变量也保存在内存中，直到没有任何指针指向它们，所以从它们被创建开始就具有相互独立的生命周期。</p>
<p>另一方面（虽然不太可能），由于一个指针导致的间接引用（一个进程执行了另一个地址），指针的过度频繁使用也会导致性能下降。</p>
<p>指针也可以指向另一个指针，并且可以进行任意深度的嵌套，导致你可以有多级的间接引用，但在大多数情况这会使你的代码结构不清晰。</p>
<p>如我们所见，在大多数情况下 Go 语言可以使程序员轻松创建指针，并且隐藏间接引用，如：自动反向引用。</p>
<p>对一个空指针的反向引用是不合法的，并且会使程序崩溃：</p>
<p>示例 4.23 <a href="examples/chapter_4/testcrash.go">testcrash.go</a>:</p>
<pre tabindex="0"><code>package main
func main() {
	var p *int = nil
	*p = 0
}
// in Windows: stops only with: &lt;exit code=&#34;-1073741819&#34; msg=&#34;process crashed&#34;/&gt;
// runtime error: invalid memory address or nil pointer dereference
</code></pre><p><strong>问题 4.2</strong> 列举 Go 语言中 <code>*</code> 号的所有用法。</p>

		</div>
	</div>
</div>


<div class="container">
    
    <div class="row">
        
        <div class="col-5">
            <a class="page-link link-dark text-end dh" href="/post/golang/2022.07.05-%E6%97%B6%E9%97%B4%E5%92%8C%E6%97%A5%E6%9C%9F/">
                <h5>前一篇</h5><br>
                Go程序的时间和日期
            </a>            
        </div>
        
        <div class="col-2">
        </div>
        
        <div class="col-5">
            <a class="page-link link-dark text-start dh" href="/post/golang/2022.07.07-%E6%8E%A7%E5%88%B6%E7%BB%93%E6%9E%84/">
                <h5>后一篇</h5><br>
                Go程序的控制结构
            </a>            
        </div>
        
    </div>
    
</div>

        </div><br><br>
<footer class="container">
    <h2>友情链接</h2>
    <hr>
    <nav class="nav nav-pills flex-column flex-sm-row">
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/gnzg/index.html" target="_blank">孤鸟之歌</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/mm/index.html" target="_blank">生成随机字符</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/md/index.html" target="_blank">MarkDown</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://gitee.com/" target="_blank">Gitee</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://github.com/" target="_blank">Github</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.aliyun.com/" target="_blank">阿里云</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://cloud.tencent.com/" target="_blank">腾讯云</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.oschina.net/" target="_blank">OSCHINA开源中国</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://gitee.com/wiseai/the-way-to-go_ZH_CN/blob/master/eBook/directory.md" target="_blank">the way to go</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://topgoer.com/" target="_blank">golang文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://goframe.org/display/gf" target="_blank">GoFrame</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.aliyundrive.com/" target="_blank">阿里云盘</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://cn.vuejs.org/" target="_blank">vue3文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://element-plus.gitee.io/zh-CN/" target="_blank">element-plus文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.runoob.com/vue3/vue3-tutorial.html" target="_blank">vue3菜鸟教程</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://v5.bootcss.com/" target="_blank">bootstrap v5 中文文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.bootstrap.cn/" target="_blank">bootstrap文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://caddy2.dengxiaolong.com/docs/" target="_blank">caddy中文教程</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.58pic.com/" target="_blank">千图</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://ifonts.com/" target="_blank">iFonts</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://marketing.qiniu.com/" target="_blank">七牛云</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.ixigua.com/" target="_blank">西瓜视频</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/yugang/index.html" target="_blank">鱼缸计算</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://justcc.mengkang.net/#/" target="_blank">C语言JustCC</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/pptist/" target="_blank">PPTist</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="/index.xml" target="_blank">RSS</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.kancloud.cn/idcpj/python/418553" target="_blank">参考资料</a>
        
    </nav>

    <div class="copyright text-center">
      <span class="power-by">
        Powered by <a class="links" href="https://gohugo.io" target="_blank">Hugo</a>
    </span>
    <span>|</span>
    <span>
        Theme - <a class="links" href="https://github.com/wiseai-go/blog-hugo" target="_blank">WiseAI</a>
    </span>
    <br>
    <span class="copyright-year">
        &copy;
        
        2017 -
        2023<span>
            陇ICP备15000157号
            
        </span></span>

</div>
</footer>
<script src="/js/bootstrap.bundle.min.js"></script>


</body>
</html>
